﻿using LeRenard.ScriptWars.Model.Entities;
using LeRenard.ScriptWars.Model.GridSystem;
using LeRenard.ScriptWars.Model.Scripting;
using System.Collections;
using System.Collections.Generic;

namespace LeRenard.ScriptWars.Model
{
    /// <summary>
    /// Defines a basic game.
    /// </summary>
    public class Game : IGame
    {
        /// <summary>
        /// The game's grid.
        /// </summary>
        public IGrid<IEntity> Grid { get { return _grid; } }
        private readonly IGrid<IEntity> _grid;

        /// <summary>
        /// Amount of turns.
        /// </summary>
        public int Turns { get { return _turns; } }
        private int _turns;

        /// <summary>
        /// Gets the cell that's currently doing it's turn.
        /// </summary>
        public IGridCell<IEntity> CurrentTurnCell { get { return _currentTurnCell; } }
        private IGridCell<IEntity> _currentTurnCell;

        /// <summary>
        /// Gets the cell that's doing it's turn next.
        /// </summary>
        public IGridCell<IEntity> NextTurnCell { get { return null; } }

        /// <summary>
        /// Holds the current position for the Next method.
        /// </summary>
        private GridPosition _currentPosition;

        /// <summary>
        /// Creates a new game.
        /// </summary>
        /// <param name="scripts">The types of scripts to participate.</param>
        /// <param name="gridSize">The size of the grid.</param>
        public Game(IEnumerable<IScript> scripts, GridSize gridSize)
        {
            ThrowIf.Null(() => scripts);
            ThrowIf.Null(() => gridSize);

            var initializer = new RandomEntityGridInitializer(scripts);
            _grid = new Grid<IEntity>(gridSize, initializer);
            _currentPosition = new GridPosition(0, 0);
            _turns = 0;
        }

        /// <summary>
        /// Evolves the board.
        /// </summary>
        public void Next()
        {
            int x = _currentPosition.X; 
            int y = _currentPosition.Y;
            do {
                x = _currentPosition.X + 1;

                if (x == _grid.Size.Width) {
                    x = 0;
                    y = _currentPosition.Y + 1;

                    if (y == _grid.Size.Height) {
                        y = 0;
                    }
                }

                _currentPosition = new GridPosition(x, y);
            } while(_grid.Layout[y, x].Value == null);            

            var cell = _grid.Layout[y, x];
            cell.Value.NextTurn(this);
            _currentTurnCell = cell;
            _turns++;
        }
    }
}
